// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraVerbMessageHelpers.h"

#include "GameFramework/Pawn.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/PlayerState.h"
#include "GameplayEffectTypes.h"
#include "Messages/LyraVerbMessage.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraVerbMessageHelpers)

//////////////////////////////////////////////////////////////////////
// FLyraVerbMessage

/**
 * 返回动词消息的字符串表示形式，用于调试
 * @return 消息的字符串表示
 */
FString FLyraVerbMessage::ToString() const
{
	FString HumanReadableMessage; // 存储可读字符串
	FLyraVerbMessage::StaticStruct()->ExportText(/*out*/ HumanReadableMessage, this, /*Defaults=*/ nullptr, /*OwnerObject=*/ nullptr, PPF_None, /*ExportRootScope=*/ nullptr); // 将结构体导出为文本
	return HumanReadableMessage; // 返回生成的字符串
}

//////////////////////////////////////////////////////////////////////
// 

/**
 * 从对象获取玩家状态
 * @param Object 输入对象
 * @return 关联的玩家状态，如果无法获取则返回nullptr
 */
APlayerState* ULyraVerbMessageHelpers::GetPlayerStateFromObject(UObject* Object)
{
	if (APlayerController* PC = Cast<APlayerController>(Object)) // 如果对象是玩家控制器
	{
		return PC->PlayerState; // 返回玩家控制器关联的玩家状态
	}

	if (APlayerState* TargetPS = Cast<APlayerState>(Object)) // 如果对象是玩家状态
	{
		return TargetPS; // 直接返回玩家状态
	}
	
	if (APawn* TargetPawn = Cast<APawn>(Object)) // 如果对象是Pawn
	{
		if (APlayerState* TargetPS = TargetPawn->GetPlayerState()) // 获取Pawn的玩家状态
		{
			return TargetPS; // 返回玩家状态
		}
	}
	return nullptr; // 无法获取时返回nullptr
}

/**
 * 从对象获取玩家控制器
 * @param Object 输入对象
 * @return 关联的玩家控制器，如果无法获取则返回nullptr
 */
APlayerController* ULyraVerbMessageHelpers::GetPlayerControllerFromObject(UObject* Object)
{
	if (APlayerController* PC = Cast<APlayerController>(Object)) // 如果对象是玩家控制器
	{
		return PC; // 直接返回玩家控制器
	}

	if (APlayerState* TargetPS = Cast<APlayerState>(Object)) // 如果对象是玩家状态
	{
		return TargetPS->GetPlayerController(); // 返回玩家状态关联的玩家控制器
	}

	if (APawn* TargetPawn = Cast<APawn>(Object)) // 如果对象是Pawn
	{
		return Cast<APlayerController>(TargetPawn->GetController()); // 返回Pawn的控制器（转换为玩家控制器）
	}

	return nullptr; // 无法获取时返回nullptr
}

/**
 * 将动词消息转换为游戏提示参数
 * @param Message 输入的动词消息
 * @return 转换后的游戏提示参数
 */
FGameplayCueParameters ULyraVerbMessageHelpers::VerbMessageToCueParameters(const FLyraVerbMessage& Message)
{
	FGameplayCueParameters Result; // 创建游戏提示参数实例

	Result.OriginalTag = Message.Verb; // 设置原始标签
	Result.Instigator = Cast<AActor>(Message.Instigator); // 转换并设置发起者
	Result.EffectCauser = Cast<AActor>(Message.Target); // 转换并设置效果引起者
	Result.AggregatedSourceTags = Message.InstigatorTags; // 设置聚合源标签
	Result.AggregatedTargetTags = Message.TargetTags; // 设置聚合目标标签
	//@TODO: = Message.ContextTags; // 待办：设置上下文标签
	Result.RawMagnitude = Message.Magnitude; // 设置原始幅度

	return Result; // 返回转换后的参数
}

/**
 * 将游戏提示参数转换为动词消息
 * @param Params 输入的游戏提示参数
 * @return 转换后的动词消息
 */
FLyraVerbMessage ULyraVerbMessageHelpers::CueParametersToVerbMessage(const FGameplayCueParameters& Params)
{
	FLyraVerbMessage Result; // 创建动词消息实例
	
	Result.Verb = Params.OriginalTag; // 设置动词标签
	Result.Instigator = Params.Instigator.Get(); // 设置发起者对象
	Result.Target = Params.EffectCauser.Get(); // 设置目标对象
	Result.InstigatorTags = Params.AggregatedSourceTags; // 设置发起者标签容器
	Result.TargetTags = Params.AggregatedTargetTags; // 设置目标标签容器
	//@TODO: Result.ContextTags = ???; // 待办：设置上下文标签容器
	Result.Magnitude = Params.RawMagnitude; // 设置幅度值

	return Result; // 返回转换后的消息
}